<template>
  <el-dialog v-model="visible" title="api选择" @close="handleDialogClose" width="80%">
    <div class="app-dialog">
      <div class="conn-api-left" :style="{ height: leftHeight }">
        <!-- <nav>API所属应用</nav> -->
        <div class="content">
          <el-input placeholder="请输入名称搜索" v-model="appNameLike" class="input-with-select">
            <el-button icon="el-icon-search" :autofocus="true" @click="getAllList()"></el-button>
          </el-input>
          <div class="conetnt-box">
            <el-button
              :class="{ 'conetnt-btn': true, a: btnVal === index }"
              v-for="(item, index) in applicationList"
              :key="index"
              @click="getAppList(index)"
            >{{ item.appName }}</el-button
            >
          </div>
        </div>
      </div>
      <div class="conn-api-right" ref="rightRef">
        <!-- 顶部查询功能 -->
        <el-form :model="queryParams" ref="queryForm" v-show="showSearch" label-width="100px">
          <el-row>
            <el-col :span="12">
              <el-form-item label="API编码" prop="apiCodeLike">
                <el-input
                  v-model="queryParams.apiCodeLike"
                  placeholder="请输入API编码"
                  clearable
                  style="width: 240px"
                  @keyup.enter="handleQuery"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="API服务名" prop="apiNameLike">
                <el-input
                  v-model="queryParams.apiNameLike"
                  placeholder="请输入API服务名"
                  clearable
                  style="width: 240px"
                  @keyup.enter="handleQuery"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="API类型" prop="apiType">
                <el-radio-group v-model="queryParams.apiType">
                  <el-radio key="" label="">全部</el-radio>
                  <el-radio
                    v-for="dict in apiTypeOptions"
                    :key="dict.dictValue"
                    :label="dict.dictValue"
                  >{{ dict.dictLabel }}</el-radio
                  >
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="请求路径" prop="apiUrlLike">
                <el-input
                  v-model="queryParams.apiUrlLike"
                  placeholder="请输入请求路径"
                  clearable
                  style="width: 240px"
                  @keyup.enter="handleQuery"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24" :offset="20">
              <el-form-item>
                <search-button @click="handleQuery" :perm="['conn:api:search']" />
                <reset-button @click="resetQuery" :perm="['conn:api:search']" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <el-row :gutter="10" class="mb8">
          <right-toolbar
            :showSearch="showSearch"
            @query-table="getList"
            :perm="['conn:api:search']"
          />
        </el-row>
        <!-- 页面主体表格 -->
        <el-table v-loading="loading" :data="dataList" @select="handleApiSelect">
          <el-table-column type="selection" width="55" />
          <el-table-column label="序号" type="index" width="55" align="center" />
          <el-table-column
            label="接口编码"
            prop="apiCode"
            :show-overflow-tooltip="true"
            min-width="100"
          />
          <el-table-column
            label="接口名称"
            prop="apiName"
            :show-overflow-tooltip="true"
            min-width="100"
          />
          <el-table-column
            label="所属应用"
            prop="appName"
            :show-overflow-tooltip="true"
            min-width="100"
          />
          <el-table-column
            label="接口类型"
            prop="apiType"
            :show-overflow-tooltip="true"
            width="100"
          >
            <template #default="scope">
              <span>{{ selectDictLabel(apiTypeOptions, scope.row.apiType) }}</span>
              <!-- <span>{{ scope.row.apiType === 1 ? 'webservice' : scope.row.apiType === 2 ? 'restful' : 'jms' }}</span> -->
            </template>
          </el-table-column>
          <el-table-column
            label="请求路径"
            prop="apiUrl"
            :show-overflow-tooltip="true"
            min-width="140"
          />
          <el-table-column label="默认版本" prop="apiMasterVersion" width="80" align="center">
            <template #default="scope">
              <span>{{ `V${scope.row.apiMasterVersion}` }}</span>
            </template>
          </el-table-column>
          <el-table-column label="更新时间" prop="updateTime" align="center" width="170" />
        </el-table>
        <pagination
          v-show="total > 0"
          :total="total"
          v-model:page="queryParams.pageNum"
          v-model:limit="queryParams.pageSize"
          @pagination="getList"
        />
      </div>
    </div>

    <template #footer>
      <dialog-footer @ok="submit" @cancel="handleDialogClose" />
    </template>
  </el-dialog>
</template>

<script>
import { listAppAll } from '@/platform/uni/api/uni/app/info/index.js'
import * as api from '@/api/conn/api/index.js'
import { debounceWrapper } from '@/utils/zmids.ts'
// import { PrismEditor } from "vue-prism-editor";
import Prism from 'prismjs'
// import "vue-prism-editor/dist/prismeditor.min.css"; // import the styles somewhere
// import highlighting library (you can use any library you want just return html string)
import { highlight, languages } from 'prismjs/components/prism-core'
import 'prismjs/components/prism-clike'
import 'prismjs/components/prism-javascript'
import 'prismjs/themes/prism-tomorrow.css' // import syntax highlighting styles
import { Base64 } from 'js-base64'
import { ElMessage } from 'element-plus'
// import MonacoEditor from '@/platform/code/views/code/components/avue-form-design/utils2/monaco-editor.js'

export default {
  // 此处的名字需要与菜单中Path一致，否则多Tab页切换时会刷新
  name: 'ConnApi',
  components: {
    // MonacoEditor
  },
  props: {
    modelValue: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      visible: false,
      hasJsonFlag: true, // json是否验证通过
      editorValue: '{key:"value"}',
      lineNumbers: true, // true为编辑模式， false只展示不可编辑
      steps: [
        { key: 'JBXX', title: '基本信息' },
        { key: 'QQT', title: '请求头' },
        { key: 'SRCS', title: '输入参数' },
        { key: 'SCCS', title: '输出参数' },
        { key: 'CSFB', title: '测试/发布' }
      ],
      batchInVisible: false,
      batchOutVisible: false,
      // 接口获取行详情
      rowInfo: {},
      // 查看详情弹框
      viewVisible: false,
      // 详情tab是否显示版本
      showVersion: true,
      // 运行结果
      operationResults: '',
      disable: false,
      value: true,
      btnVal: 0,
      // 左侧应用栏列表
      applicationList: [],
      // 遮罩层
      loading: false,
      allLoading: false,
      //输入表格遮罩层
      SearchLoading: false,
      //输出表格遮罩层
      insertLoading: false,
      // 输入表格数据
      inputList: [],
      apiParamsBody: '1',
      // 输入表格支持参数属性
      inparamWithAttr: false,
      // 输出表格数据
      insertList: [],
      // 请求头表格
      reqHeaderList: [],
      // 响应头表格
      resHeaderList: [],
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 表格数据
      dataList: [],
      // 输出表格数据
      outputList: [],
      // 输出表格支持参数属性
      outparamWithAttr: false,
      // 所属应用可选列表
      applicationOptions: [],
      // 服务方法
      wsOperationList: [],
      // 参数类型选项
      nodeTypeList: [
        { dictValue: 'string', dictLabel: '字符串 (String)' },
        { dictValue: 'long', dictLabel: '整数 (Long)' },
        { dictValue: 'decimal', dictLabel: '小数 (Decimal)' },
        { dictValue: 'object', dictLabel: '对象 (Object)' },
        { dictValue: 'array', dictLabel: '数组 (Array)' }
      ],
      qqtNodeTypeList: [
        { dictValue: 'string', dictLabel: '字符串 (String)' },
        { dictValue: 'long', dictLabel: '整数 (Long)' },
        { dictValue: 'decimal', dictLabel: '小数 (Decimal)' }
      ],
      elementTypeList: [],
      // API类型的固定字典选项列表
      apiTypeOptions: [],
      // 可选接口请求方式
      requestMethodOptions: [
        { dictValue: '1', dictLabel: 'GET' },
        { dictValue: '2', dictLabel: 'POST' }
      ],
      // API状态的固定字典选项列表
      apiStatusOptions: [
        { dictValue: '0', dictLabel: '生效' },
        { dictValue: '1', dictLabel: '暂存' },
        { dictValue: '2', dictLabel: '停用' }
      ],
      // 是否删除的固定字典选项列表
      deleteFlagOptions: [
        { dictValue: 'Y', dictLabel: '是' },
        { dictValue: 'N', dictLabel: '否' }
      ],
      jmsDatasource: [],
      // 右侧查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        // API编码
        apiCodeLike: '',
        // API服务名
        apiNameLike: '',
        // API类型
        apiType: '',
        // url
        apiUrlLike: '',
        // API状态
        apiStatus: '0'
      },
      //左侧应用列表查询参数
      appNameLike: '',
      leftHeight: 'auto',
      // 新增/修改弹窗s
      editForm: {
        // 步骤控制
        stepIndex: 0,
        // 当前最大步骤
        maxIndex: 0,
        // 控制 dialog
        open: false,
        // 控制 修改/保存
        isAdd: true,
        // 弹出层标题
        title: '',
        // 表单参数
        data: {},
        // 规则
        rules: {
          // API编码
          apiCode: [
            { required: true, message: 'API编码不可以为空', trigger: 'blur' },
            {
              min: 1,
              max: 32,
              message: 'API编码的长度最多 32 个字符',
              trigger: 'blur'
            }
          ],
          // API服务名
          apiName: [
            { required: true, message: 'API服务名不可以为空', trigger: 'blur' },
            {
              min: 1,
              max: 64,
              message: 'API服务名的长度最多 64 个字符',
              trigger: 'blur'
            }
          ],
          apiDesc: [{ required: true, message: 'API描述不可以为空', trigger: 'blur' }],
          // API类型
          apiType: [{ required: true, message: 'API类型不可以为空', trigger: 'blur' }],
          // 所属应用
          appId: [{ required: true, message: '所属应用不可以为空', trigger: 'blur' }],
          // 请求路径
          apiUrl: [{ required: true, message: '请求路径不可以为空', trigger: 'blur' }],
          // 服务方式
          wsOperation: [
            {
              required: true,
              message: '服务方式不可以为空',
              trigger: 'change'
            }
          ],
          wsdlUrlOrigin: [
            {
              required: true,
              message: 'WSDL来源不可以为空',
              trigger: 'blur'
            }
          ],
          // 超时时间
          timeoutSecs: [{ required: true, message: '超时时间不可以为空', trigger: 'blur' }],
          jmsDatasourceCode: [{ required: true, message: 'JMS数据源不可以为空', trigger: 'blur' }],
          jmsDestinationName: [{ required: true, message: '名称不可以为空', trigger: 'blur' }],
          // 响应时间
          alarmSecs: [{ required: true, message: '响应时间不可以为空', trigger: 'blur' }],
          // 失败重试次数
          retryTimes: [
            {
              required: true,
              message: '失败重试次数不可以为空',
              trigger: 'blur'
            }
          ],
          // 请求方式
          httpRequestMethod: [{ required: true, message: '请求方式不可以为空', trigger: 'blur' }]
        }
      },
      testForm: {
        // 控制 dialog
        open: false,
        // 弹出层标题
        title: '测试Api接口',
        // 表单参数
        data: {}
      },
      // 新增请求头/响应头弹窗
      qqtForm: {
        isAdd: true,
        open: false,
        title: '',
        state: 'req',
        // 表单参数
        data: {},
        // 规则
        rules: {
          // 参数类型
          nodeType: [{ required: true, message: '参数类型不可以为空', trigger: 'blur' }],
          elementType: [{ required: true, message: '元素类型不可以为空', trigger: 'blur' }],
          // 参数名称
          nodeName: [{ required: true, message: '参数名不可以为空', trigger: 'blur' }],
          // 参数描述
          nodeLabel: [{ required: true, message: '参数描述不可以为空', trigger: 'blur' }]
          // 字段校验规则
          // nodeCheckRegex: [
          //   { required: true, message: '校验规则不可以为空', trigger: 'blur' }
          // ],
        }
      },
      // 新增输入/输出参数弹窗
      inputForm: {
        // 是否添加属性
        isAttr: false,
        // 控制 dialog
        open: false,
        // 弹出层标题
        title: '',
        // 父节点
        parentNode: '根节点',
        // 父节点Id
        nodeParentId: '0',
        // 输入/输出状态
        state: '1',
        // 表单参数
        data: {},
        // 规则
        rules: {
          // 参数类型
          nodeType: [{ required: true, message: '参数类型不可以为空', trigger: 'blur' }],
          elementType: [{ required: true, message: '元素类型不可以为空', trigger: 'blur' }],
          // 参数名称
          nodeName: [{ required: true, message: '参数名不可以为空', trigger: 'blur' }],
          // 参数描述
          nodeLabel: [{ required: true, message: '参数描述不可以为空', trigger: 'blur' }]
          // 字段校验规则
          // nodeCheckRegex: [
          //   { required: true, message: '校验规则不可以为空', trigger: 'blur' }
          // ],
        }
      },
      // 升级接口API弹窗
      upgradeForm: {
        // 升级
        isUpgrade: false,
        isEdit: false,
        // 控制 dialog
        open: false,
        // 弹出层标题
        title: '',
        // 表单参数
        data: {},
        // 规则
        rules: {
          // 服务URL
          apiUrl: [{ required: true, message: '服务URL不可以为空', trigger: 'blur' }],
          // 请求方式
          httpRequestMethod: [{ required: true, message: '请求方式不可以为空', trigger: 'blur' }],
          // 升级说明
          apiVerDesc: [{ required: true, message: '升级说明不可以为空', trigger: 'blur' }]
        }
      },
      // 升级接口API弹窗
      editionForm: {
        // 控制 dialog
        open: false,
        // 遮罩层
        loading: false,
        // 弹出层标题
        title: '查看API接口版本',
        // 表单参数
        data: {},
        // 是否需修改
        isAdd: false,
        // 表单列表数据
        list: []
      },
      // 上传JSON参数
      upload: {
        // 是否显示弹出层（上传JSON参数）
        open: false,
        // 弹出层标题（上传JSON参数）
        title: '',
        // 是否禁用上传
        isUploading: false,
        // 是否更新已经存在的用户数据
        updateSupport: 0,
        // 上传的地址
        url: import.meta.env.VITE_APP_BASE_API + '/conn/api/importApi',
        // 上传的ID（为空表示创建）
        ids: null
      },
      fileList: [],
      options2: {
        fullScreen: false,
        minimap: {
          enabled: false
        }
      },
      selection: []
    }
  },
  watch: {
    'inputForm.open'(val) {
      if (!val) {
        this.inputForm.title = ''
        this.inputForm.isAttr = false
        this.inputForm.parentNode = '根节点'
        this.inputForm.nodeParentId = '0'
        this.inputForm.state = '1'
        this.inputReset()
      }
    },
    'editForm.open'(val) {
      if (!val) {
        this.upgradeForm.isUpgrade = false
        this.upgradeForm.isEdit = false
        this.editForm.title = ''
        this.editForm.stepIndex = 0
        this.editForm.maxIndex = 0
        this.editForm.isAdd = true
        this.reset()
      }
    },
    'upgradeForm.open'(val) {
      if (!val) {
        this.upgradeForm.data = {}
      }
    },
    'inputForm.data'(val) {},
    'testForm.open'(val) {
      if (!val) {
        this.inputList = []
      }
    },
    modelValue: {
      handler(val) {
        this.visible = val
      },
      immediate: true
    }
  },
  created() {
    // 查询列表
    this.getList()
    this.getAllList()
    this.getDicts('uni_element_type').then((response) => {
      this.elementTypeList = response.data
    })
    // 获取数据字典：conn_protocol_type
    this.getDicts('conn_protocol_type').then((response) => {
      this.apiTypeOptions = response.data
      console.log('apiTypeOptions', this.apiTypeOptions)
    })
  },
  mounted() {
    Prism.highlightAll()
  },
  methods: {
    highlighter(code) {
      return highlight(code, languages.js) //returns html
    },
    // 左侧应用列表调用
    getAppList(val) {
      this.btnVal = val
      this.queryParams.pageNum = 1
      if (this.btnVal === 0) {
        this.appNameLike = ''
        this.queryParams.appId = ''
        this.getList()
        this.getAllList()
      } else {
        this.queryParams.appId = this.applicationList[this.btnVal].appId
        this.getList()
      }
    },
    // 查询列表
    getList: debounceWrapper(function () {
      this.loading = true
      api.search(this.queryParams).then((response) => {
        this.$nextTick(() => {
          //获取右侧动态盒子高度，赋值给左侧
          if (this.$refs.rightRef) {
            let height = this.$refs.rightRef.offsetHeight
            this.leftHeight = height
          }
        })
        this.dataList = response.data.list
        this.total = response.data.total
        this.loading = false
      })
    }),
    // 查询应用列表
    getAllList: debounceWrapper(function () {
      this.allLoading = true
      listAppAll(this.appNameLike).then((response) => {
        this.applicationList = [{ appName: '所有应用' }]
        this.applicationList = this.applicationList.concat(response.data)
        this.allLoading = false
      })
    }),
    // 请求头参数列表
    getReqHeaderList(apiId, apiVerId, apiVersion) {
      this.SearchLoading = true
      this.reqHeaderList = []
      api.reqHeaderSearch({ apiId, apiVerId, apiVersion }).then((response) => {
        this.reqHeaderList = response.data
        this.SearchLoading = false
      })
    },
    // 响应头参数列表
    getResHeaderList(apiId, apiVerId, apiVersion) {
      this.SearchLoading = true
      this.resHeaderList = []
      api.resHeaderSearch({ apiId, apiVerId, apiVersion }).then((response) => {
        this.resHeaderList = response.data
        this.SearchLoading = false
      })
    },
    // 查询输入参数列表
    getSearchTree: debounceWrapper(function (apiId, apiVerId) {
      this.SearchLoading = true
      this.inputList = []
      api.searchTree({ apiId, apiVerId }).then((response) => {
        this.inputList = response.data
        this.SearchLoading = false
      })
    }),
    // 查询输出参数列表
    getoutSearchTree: debounceWrapper(function (apiId, apiVerId) {
      this.insertLoading = true
      this.insertList = []
      api.outSearchTree({ apiId: apiId, apiVerId: apiVerId }).then((response) => {
        this.insertList = response.data
        this.insertLoading = false
      })
    }),
    // 查询版本列表参数
    getEditionList: debounceWrapper(function () {
      this.editionForm.list = []
      api.searchAllByEntity(this.editionForm.data.apiId).then((response) => {
        this.editionForm.list = response.data || []
        this.editionForm.loading = false
      })
    }),
    // 搜索按钮操作
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    // 重置按钮操作
    resetQuery() {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    // 下一步按钮操作  stepIndex 步骤条进度; val 1：暂存 2：下一步
    nextStep(val) {
      let stepIndex = this.editForm.stepIndex
      let maxIndex = this.editForm.maxIndex

      if (stepIndex === 0) {
        if (!this.disable) {
          if (this.editForm.data.apiType === '1' && this.wsOperationList.length === 0) {
            this.fileList.length === 0 && this.$message.error('请上传WSDL文件！')
          }
          this.$refs['formRef'].validate(async (valid) => {
            if (!valid) return
            let promise
            if (this.upgradeForm.isUpgrade) {
              promise = api.upgradeApi
            } else if (this.upgradeForm.isEdit) {
              promise = api.updateReturnId
            } else {
              promise = this.editForm.isAdd ? api.insertReturnId : api.updateReturnId
            }
            const response = await promise(this.editForm.data)
            if (response.code === '200') {
              if (val === 1) {
                if (this.upgradeForm.isUpgrade || this.upgradeForm.isEdit) {
                  this.getEditionList()
                }
                this.editForm.open = false
                this.handleQuery()
                return
              }
              this.editForm.data.apiId = response.data.apiId
              this.editForm.data.apiVerId = response.data.apiVerId
              response.data.apiVersion && (this.editForm.data.apiVersion = response.data.apiVersion)

              this.getReqHeaderList(
                this.editForm.data.apiId,
                this.editForm.data.apiVerId,
                this.editForm.data.apiVersion
              )
              this.getResHeaderList(
                this.editForm.data.apiId,
                this.editForm.data.apiVerId,
                this.editForm.data.apiVersion
              )
              this.editForm.stepIndex++
              stepIndex + 1 > maxIndex ? this.editForm.maxIndex++ : this.editForm.maxIndex
            }
          })
        } else {
          this.getReqHeaderList(
            this.editForm.data.apiId,
            this.editForm.data.apiVerId,
            this.editForm.data.apiVersion
          )
          this.getResHeaderList(
            this.editForm.data.apiId,
            this.editForm.data.apiVerId,
            this.editForm.data.apiVersion
          )
          this.editForm.stepIndex++
          stepIndex + 1 > maxIndex ? this.editForm.maxIndex++ : this.editForm.maxIndex
        }
      } else if (stepIndex === 1) {
        this.getSearchTree(this.editForm.data.apiId, this.editForm.data.apiVerId)
        this.editForm.stepIndex++
        stepIndex + 1 > maxIndex ? this.editForm.maxIndex++ : this.editForm.maxIndex
      }
      if (this.steps[stepIndex].key === 'SRCS') {
        api
          .updateRowNotNullById({
            apiVerId: this.editForm.data.apiVerId,
            apiParamsBody: this.apiParamsBody,
            inparamWithAttr: this.inparamWithAttr ? 'Y' : 'N'
          })
          .then(() => {
            this.getoutSearchTree(this.editForm.data.apiId, this.editForm.data.apiVerId)
            this.editForm.stepIndex++
            stepIndex + 1 > maxIndex ? this.editForm.maxIndex++ : this.editForm.maxIndex
          })
      } else if (this.steps[stepIndex].key === 'SCCS') {
        api
          .updateRowNotNullById({
            apiVerId: this.editForm.data.apiVerId,
            outparamWithAttr: this.outparamWithAttr ? 'Y' : 'N'
          })
          .then(() => {
            this.editForm.stepIndex++
            stepIndex + 1 > maxIndex ? this.editForm.maxIndex++ : this.editForm.maxIndex
            api.selectById(this.editForm.data.apiId, this.editForm.data.apiVersion).then((res) => {
              if (res.code === '200') {
                this.editForm.data.apiCode = res.data.apiCode
                this.editForm.data.contentId = res.data.contentId
              }
            })
          })
      }
      if (val === 1 && stepIndex !== 0) {
        if (this.upgradeForm.isUpgrade || this.upgradeForm.isEdit) {
          this.getEditionList()
        }
        this.editForm.open = false
        this.handleQuery()
      }
    },
    // 步骤条按钮操作
    previousStep(val) {
      if (val < this.editForm.maxIndex + 1) {
        this.editForm.stepIndex = val
      }
    },
    // 表单重置
    reset() {
      this.editForm.stepIndex = 0
      this.editForm.maxIndex = 0
      this.editForm.isAdd = true
      this.editForm.data.wsOperation = ''
      this.wsOperationList = []
      this.editForm.data = {
        // API主键
        apiId: '',
        // API编码
        apiCode: '',
        // API服务名
        apiName: '',
        // 所属应用
        appId: '',
        // 接口类型
        apiType: '',
        // 请求路径
        apiUrl: '',
        jmsDatasourceCode: '',
        jmsDestinationName: '',
        jmsType: 'queue',
        jmsRole: 'C',
        // 超时时间
        timeoutSecs: '0',
        // 响应时间
        alarmSecs: '120',
        // 失败重试次数
        retryTimes: '0',
        // 请求方式
        httpRequestMethod: 'POST',
        wsdlUrlOrigin: 'N'
      }
      // 重置字段校验
      this.$refs.formRef && this.$refs.formRef.clearValidate()
      this.resetForm('formRef')
    },
    // 表单重置
    inputReset() {
      this.inputForm.isAdd = true
      this.qqtForm.state = 'req'
      this.inputForm.data = {
        // 版本主键id
        apiVerId: this.editForm.data.apiVerId || '',
        // 主键id
        apiId: this.editForm.data.apiId || '',
        apiVersion: this.editForm.data.apiVersion || '',
        // 输入类型
        nodeType: '',
        elementType: '',
        // 输入参数名
        nodeName: '',
        // 参数描述
        nodeLabel: '',
        // 节点是否必须
        nodeNeededable: true,
        // 字段值校验正则表达式
        nodeCheckRegex: '',
        // 节点是否必填
        nodeValueable: true
      }
      // 重置字段校验
      this.$refs.inputformRef && this.$refs.inputformRef.clearValidate()
      this.resetForm('inputformRef')
    },
    qqtRest() {
      this.qqtForm.isAdd = true
      this.qqtForm.data = {
        // 版本主键id
        apiVerId: this.editForm.data.apiVerId || '',
        // 主键id
        apiId: this.editForm.data.apiId || '',
        apiVersion: this.editForm.data.apiVersion || '',
        // 输入类型
        nodeType: '',
        // 输入参数名
        nodeName: '',
        // 参数描述
        nodeLabel: '',
        // 节点是否必须
        nodeNeededable: true,
        // 字段值校验正则表达式
        nodeCheckRegex: '',
        // 节点是否必填
        nodeValueable: true
      }
      // 重置字段校验
      this.$refs.qqtformRef && this.$refs.qqtformRef.clearValidate()
      this.resetForm('qqtformRef')
    },
    // 新增按钮操作
    handleAdd() {
      this.disable = false
      this.fileList = []
      this.reset()
      listAppAll().then((response) => {
        this.applicationOptions = response.data
        this.editForm.data.appId = this.queryParams.appId
      })
      this.editForm.open = true
      this.editForm.title = '新增源服务API'
    },
    // 查看详情
    handleView(row, showVersion) {
      this.rowInfo = row
      this.showVersion = showVersion === 'showVersion'
      this.viewVisible = true
      api.selectById(row.apiId, row.apiVersion).then((response) => {
        this.rowInfo = response.data
      })
    },
    // 查看详情
    handleExport(row) {
      console.log(import.meta.env.VITE_APP_GATEWAY_URL + '/conn/api/exportApi/' + row.apiId)
      this.downloadUrl(import.meta.env.VITE_APP_GATEWAY_URL + '/conn/api/exportApi/' + row.apiId)
      this.msgSuccess('正在启动导出......')
    },
    handleExportWSDL(row) {
      console.log(
        import.meta.env.VITE_APP_GATEWAY_URL + '/conn/public/download/wsdl/' + row.wsdlContentId
      )
      this.downloadUrl(
        import.meta.env.VITE_APP_GATEWAY_URL + '/conn/public/download/wsdl/' + row.wsdlContentId
      )
      this.msgSuccess('正在启动导出......')
    },
    // 导出
    // tempExport() {
    //   const peopleAndDeptarr = [
    //     'searchCreateOperTreeCode'
    //   ]
    //   const parmas = {
    //     pageNo: this.page.currentPage,
    //     pageSize: this.page.pageSize,
    //     ...this.queryParams,
    //   }
    //   peopleAndDeptarr.forEach(n => {
    //     if (this.queryParams[n]) {
    //       parmas[n] = `${this.queryParams[n]['objectId']}:${this.queryParams[n]['objectType']}`
    //     }
    //   })
    //   exportExcel(parmas).then(res => {
    //     this.isExcel('zip', 'export', res.data)
    //   })
    // },
    // // 导出excel
    // isExcel (type, name, data) {
    //   const link = document.createElement('a')
    //   const blob = new Blob([data])
    //   link.style.display = 'none'
    //   link.href = URL.createObjectURL(blob)
    //   link.setAttribute('download', `${name}.` + type)
    //   document.body.appendChild(link)
    //   link.click()
    //   document.body.removeChild(link)
    // },
    qqtAdd(row, state, title) {
      this.qqtRest()
      this.qqtForm.state = state
      this.qqtForm.title = title
      this.qqtForm.open = true
    },
    qqtModify(row, state, title) {
      this.qqtAdd(row, state, title)
      this.qqtForm.isAdd = false
      this.qqtForm.data = {
        apiVerId: row.apiVerId || this.editForm.data.apiVerId,
        apiId: row.apiId || this.editForm.data.apiId,
        apiVersion: row.apiVersion || this.editForm.data.apiVersion,
        nodeType: row.nodeType,
        nodeName: row.nodeName,
        nodeLabel: row.nodeLabel,
        nodeNeededable: row.nodeNeededable === 'Y' ? true : false,
        nodeId: row.nodeId,
        headerId: row.headerId,
        nodeCheckRegex: row.nodeCheckRegex,
        nodeValueable: row.nodeValueable === 'Y' ? true : false
      }
    },
    handleQqtDelete(deleteIds, key) {
      let fn
      key === 'req' ? (fn = api.reqInDeleteByIds) : (fn = api.resOutDeleteByIds)
      fn(deleteIds * 1)
        .then(() => {
          this.msgSuccess('删除成功')
          key === 'req'
            ? this.getReqHeaderList(
                this.editForm.data.apiId,
                this.editForm.data.apiVerId,
                this.editForm.data.apiVersion
              )
            : this.getResHeaderList(
                this.editForm.data.apiId,
                this.editForm.data.apiVerId,
                this.editForm.data.apiVersion
              )
        })
        .catch(function () {})
    },
    // 输入输出 新增按钮操作
    inputAdd(row, state, isAttr) {
      this.inputForm.open = true
      this.inputForm.nodeParentId = row.nodeId ? row.nodeId : 0
      this.inputForm.parentNode = row.nodeName ? `${row.nodeName}(${row.nodeLabel})` : '根节点'
      this.inputForm.title = state
      this.inputForm.isAttr = isAttr
      this.inputReset()
    },
    // 修改输入参数
    modify(row, state) {
      this.inputReset()
      api.inSelectById(row.nodeParentId).then((res) => {
        if (!res.data) return
        this.inputForm.parentNode = `${res.data.nodeName}(${res.data.nodeLabel})`
      })
      this.inputForm.isAdd = false
      this.inputForm.open = true
      this.inputForm.nodeParentId = row.nodeParentId ? row.nodeParentId : 0
      this.inputForm.title = state
      this.inputForm.isAttr = row.isAttr === 'Y'
      this.inputForm.data = {
        apiVerId: row.apiVerId || this.editForm.data.apiVerId,
        apiId: row.apiId || this.editForm.data.apiId,
        apiVersion: row.apiVersion || this.editForm.data.apiVersion,
        nodeType: row.nodeType,
        nodeName: row.nodeName,
        nodeLabel: row.nodeLabel,
        nodeNeededable: row.nodeNeededable === 'Y' ? true : false,
        nodeId: row.nodeId,
        nodeCheckRegex: row.nodeCheckRegex,
        nodeValueable: row.nodeValueable === 'Y' ? true : false
      }
      this.editForm.data.apiVersion = row.apiVersion
    },
    // 升级API接口参数
    upgradeClick(row, val) {
      this.editionForm.isAdd = val ? true : false
      this.upgradeForm.open = true
      this.upgradeForm.data = {
        // 接口编码
        apiCode: row.apiCode,
        // 所属应用
        appName: row.appName,
        // 接口名称
        apiName: row.apiName,
        // API主键
        apiId: row.apiId,
        // 接口版本
        apiVersion: row.apiVersion,
        // 服务URL
        apiUrl: row.apiUrl,
        // 请求方式
        httpRequestMethod: row.httpRequestMethod,
        // 升级说明
        apiVerDesc: row.apiVerDesc
      }
      // 重置字段校验
      this.$refs.upgradeFormRef && this.$refs.upgradeFormRef.clearValidate()
      this.resetForm('upgradeFormRef')
    },
    // 获取接口版本参数
    editionClick(row) {
      this.editionForm.open = true
      this.editionForm.data = {
        // 接口编码
        apiCode: row.apiCode,
        // 所属应用
        appName: row.appName,
        // 接口名称
        apiName: row.apiName,
        // API主键
        apiId: row.apiId,
        // 接口版本
        apiVersion: row.apiVersion,
        apiMasterVersion: row.apiMasterVersion,
        // 服务URL
        apiUrl: row.apiUrl,
        // 请求方式
        httpRequestMethod: row.httpRequestMethod,
        // 升级说明
        apiVerDesc: row.apiVerDesc
      }
      this.getEditionList()
    },
    // 作废
    handleDiscard: debounceWrapper(function (row) {
      if (row) {
        this.editForm.data.apiVersion = row.apiVersion
        this.editForm.data.apiId = row.apiId
      }
      let data = {
        apiVersion: this.editForm.data.apiVersion,
        apiId: this.editForm.data.apiId
      }
      api.discard(data).then((response) => {
        this.msgSuccess('作废成功')
        if (this.editionForm.open) {
          this.getEditionList()
        } else {
          this.getList()
        }
      })
    }),
    // 删除按钮操作 val 1：主页面删除接口 2：弹窗删除输入参数 3：弹窗删除输出参数
    handleDelete: debounceWrapper(function (deleteIds, val) {
      switch (val) {
        case 1:
          api
            .deleteByIds(deleteIds * 1)
            .then(() => {
              this.msgSuccess('删除成功')
              this.getList()
            })
            .catch(function () {})
          break
        case 2:
          api
            .inDeleteByIds(deleteIds * 1)
            .then(() => {
              this.msgSuccess('删除成功')
              this.getSearchTree(this.editForm.data.apiId, this.editForm.data.apiVerId)
            })
            .catch(function () {})
          break
        case 3:
          api
            .outDeleteByIds(deleteIds * 1)
            .then(() => {
              this.msgSuccess('删除成功')
              this.getoutSearchTree(this.editForm.data.apiId, this.editForm.data.apiVerId)
            })
            .catch(function () {})
          break
        case 4:
          api
            .deleteByIdAndVersion(deleteIds)
            .then(() => {
              this.msgSuccess('删除成功')
              this.getEditionList()
            })
            .catch(function () {})
          break

        default:
          break
      }
    }),
    // 发布版本
    release: debounceWrapper(function (row, val) {
      if (row) {
        this.editForm.data.apiVerId = row.apiVerId
      }
      let data = {
        apiVerId: this.editForm.data.apiVerId
      }
      let pormise = val ? api.versionEnable(data) : api.enable(data)
      pormise.then((response) => {
        if (response.code === 200) {
          this.msgSuccess('发布成功')
          if (this.editionForm.open) {
            this.getEditionList()
          } else {
            this.getList()
          }
          this.editForm.open = false
        }
      })
    }),
    // 设置版本为默认
    masterClick: debounceWrapper(function (row) {
      api.master({ apiId: row.apiId, apiVersion: row.apiVersion }).then((response) => {
        this.editionForm.data.apiMasterVersion = row.apiVersion
        this.msgSuccess('设置成功')
        this.getEditionList()
      })
    }),
    // 撤销
    revokeClick: debounceWrapper(function (row) {
      if (row) {
        this.editForm.data.apiVersion = row.apiVersion
        this.editForm.data.apiId = row.apiId
      }
      let data = {
        apiVersion: this.editForm.data.apiVersion,
        apiId: this.editForm.data.apiId
      }
      api.revoke(data).then((response) => {
        this.msgSuccess('撤销成功')
        if (this.editionForm.open) {
          this.getEditionList()
        } else {
          this.getList()
        }
      })
    }),
    // 点击版本种升级按钮
    upgradeVersion(row) {
      this.upgradeForm.isUpgrade = true
      this.reviseUpdate(row)
    },
    editVersion(row) {
      this.upgradeForm.isEdit = true
      this.reviseUpdate({
        ...row,
        apiStatus: row.apiVerStatus
      })
    },
    // 修改按钮操作
    reviseUpdate: debounceWrapper(function (row, disable) {
      this.disable = disable ? true : false
      this.reset()
      this.editForm.isAdd = false
      listAppAll().then((response) => {
        this.applicationOptions = response.data
      })
      this.apiTypeChange(row.apiType)
      api.selectById(row.apiId, row.apiVersion).then((response) => {
        this.editForm.data = response.data
        this.apiParamsBody = response.data.apiParamsBody
        this.inparamWithAttr = response.data.inparamWithAttr === 'Y'
        this.outparamWithAttr = response.data.outparamWithAttr === 'Y'
        this.fileList = [{ name: response.data.contentName }]
        !this.disable && this.getWsOperationNames()
        this.editForm.open = true
        !disable && (this.editForm.title = '修改源服务API')
        disable && (this.editForm.title = '源服务API详细')
        this.upgradeForm.isUpgrade && (this.editForm.title = '源服务API升级')
        this.upgradeForm.isEdit && (this.editForm.title = '源服务API修改')
      })
    }),
    // 打开测试弹窗
    testUpdate: debounceWrapper(function (row) {
      this.reset()
      this.editForm.data.apiVersion = row.apiVersion
      this.editForm.data.apiId = row.apiId
      api.selectById(row.apiId, row.apiVersion).then((response) => {
        this.editForm.data = response.data
        this.inputList = response.data.inParamList
        this.testForm.open = true
      })
    }),
    submitQqtForm: debounceWrapper(function () {
      this.$refs['qqtformRef'].validate((valid) => {
        if (valid) {
          let data = { ...this.qqtForm.data }
          data.nodeNeededable = this.qqtForm.data.nodeNeededable ? 'Y' : 'N'
          data.nodeValueable = this.qqtForm.data.nodeValueable ? 'Y' : 'N'
          data.nodeCheckRegex =
            this.qqtForm.data.nodeType === 'string' || data.elementType === 'string'
              ? data.nodeCheckRegex
              : ''
          var promise
          if (this.qqtForm.isAdd) {
            promise =
              this.qqtForm.state === 'req'
                ? api.reqInParamInsert(data)
                : api.resOutParamInsert(data)
          } else {
            promise =
              this.qqtForm.state === 'req' ? api.reqInUpdateById(data) : api.resOutUpdateById(data)
          }
          promise.then((response) => {
            if (response.code === '200') {
              this.qqtForm.open = false
              this.msgSuccess(this.qqtForm.isAdd ? '新增成功' : '修改成功')
              if (this.steps[this.editForm.stepIndex].key === 'QQT') {
                if (this.qqtForm.state === 'req') {
                  this.getReqHeaderList(
                    this.editForm.data.apiId,
                    this.editForm.data.apiVerId,
                    this.editForm.data.apiVersion
                  )
                } else if (this.qqtForm.state === 'res') {
                  this.getResHeaderList(
                    this.editForm.data.apiId,
                    this.editForm.data.apiVerId,
                    this.editForm.data.apiVersion
                  )
                }
              }
            }
          })
        }
      })
    }),
    // 提交按钮  stepIndex 步骤条进度;
    submitInputForm: debounceWrapper(function () {
      this.$refs['inputformRef'].validate((valid) => {
        if (valid) {
          let data = { ...this.inputForm.data }
          data.isAttr = this.inputForm.isAttr ? 'Y' : 'N'
          data.nodeNeededable = this.inputForm.data.nodeNeededable ? 'Y' : 'N'
          data.nodeValueable = this.inputForm.data.nodeValueable ? 'Y' : 'N'
          data.nodeParentId = this.inputForm.nodeParentId
          data.elementType = this.inputForm.data.nodeType === 'array' ? data.elementType : ''
          data.nodeCheckRegex =
            this.inputForm.data.nodeType === 'string' || data.elementType === 'string'
              ? data.nodeCheckRegex
              : ''
          if (this.steps[this.editForm.stepIndex].key === 'SRCS') {
            data.apiParamsBody = this.apiParamsBody
          }
          var promise
          if (this.inputForm.isAdd) {
            promise =
              this.steps[this.editForm.stepIndex].key === 'SRCS'
                ? api.InParamInsert(data)
                : api.InParamOutInsert(data)
          } else {
            promise =
              this.steps[this.editForm.stepIndex].key === 'SRCS'
                ? api.inUpdateById(data)
                : api.outUpdateById(data)
          }
          promise.then((response) => {
            if (response.data === 1) {
              this.inputForm.open = false
              this.msgSuccess(this.inputForm.isAdd ? '新增成功' : '修改成功')
              switch (this.steps[this.editForm.stepIndex].key) {
                case 'SRCS':
                  this.getSearchTree(this.editForm.data.apiId, this.editForm.data.apiVerId)
                  break

                case 'SCCS':
                  this.getoutSearchTree(this.editForm.data.apiId, this.editForm.data.apiVerId)
                  break

                default:
                  break
              }
            }
          })
        }
      })
    }),
    // 升级按钮
    submitUpgradeForm: debounceWrapper(function () {
      this.$refs['upgradeFormRef'].validate((valid) => {
        if (valid) {
          let promise = this.editForm.isAdd
            ? api.updateRowNotNullById(this.upgradeForm.data)
            : api.upgradeApi(this.upgradeForm.data)
          promise.then((response) => {
            this.upgradeForm.open = false
            this.msgSuccess(response.data)
            this.getList()
            this.getEditionList()
          })
        }
      })
    }),
    // 取消按钮
    cancel(val) {
      this[val].open = false
      this.handleQuery()
    },
    beforeUpload(file) {
      if (!this.editForm.data.apiUrl) {
        this.$message.error('请先填写服务URL')
        return false
      }
      const FILE_NAME = file.name
      if (FILE_NAME.substring(FILE_NAME.lastIndexOf('.')) !== '.wsdl') {
        this.$message.warning('仅支持.wsdl文件')
        return false
      }
    },
    async httpRequset(n) {
      this.fileList.push(n.file)
      const res = await api.uploadWsdl({
        file: n.file,
        apiUrl: this.editForm.data.apiUrl,
        contentId: this.editForm.data.contentId, //修改、升级：此参数有值
        isUpgrade: this.upgradeForm.isUpgrade // 升级：为true
      })
      this.editForm.data.contentId = res.data || ''
      this.getWsOperationNames()
    },
    async getWsOperationNames() {
      if (this.editForm.data.apiType === '1') {
        const res = await api.selectWsdlOperationNamesByContentId({
          contentId: this.editForm.data.contentId
        })
        this.wsOperationList = res.data
      }
    },
    handleRemove(file, fileList) {
      this.fileList = fileList
    },
    onBatchOk(key, val) {
      let fn
      if (key === 'in') {
        fn = api.batchInParamInsert
      } else if (key === 'out') {
        fn = api.batchOutParamInsert
      }
      fn({
        ...val,
        apiVerId: this.editForm.data.apiVerId
      }).then((res) => {
        if (res.code === '200') {
          this.msgSuccess('批量新增成功')
          switch (this.steps[this.editForm.stepIndex].key) {
            case 'SRCS':
              this.batchInVisible = false
              this.getSearchTree(this.editForm.data.apiId, this.editForm.data.apiVerId)
              break
            case 'SCCS':
              this.batchOutVisible = false
              this.getoutSearchTree(this.editForm.data.apiId, this.editForm.data.apiVerId)
              break
            default:
              break
          }
        }
      })
    },
    apiTypeChange(val) {
      console.log(val)
      if (val === '3') {
        // apiType === jms
        api.getJmsDatasource().then((res) => {
          this.jmsDatasource = res.data || []
        })
      }
    },
    // 导入按钮
    uploadHandler(row) {
      this.upload.title = '导入API数据'
      this.upload.ids = (row && row.id) || 'create'
      this.upload.open = true
    },
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true
    },
    // 文件上传成功处理
    handleFileSuccess(response, file, fileList) {
      this.upload.open = false
      this.upload.isUploading = false
      this.$refs.upload.clearFiles()
      this.$alert(response.msg, '上传结果', { dangerouslyUseHTMLString: true })
      this.getList()
    },
    // 提交上传文件
    submitFileForm: debounceWrapper(function () {
      this.$refs.upload.submit()
    }),
    // 更多操作按钮
    async handleAction(command, row) {
      console.log('command', command)
      console.log('row', row)
      if ('export' === command) {
        // 导出
        this.handleExport(row)
      } else if ('exportWSDL' === command) {
        this.handleExportWSDL(row, 'showVersion')
      } else if ('view' === command) {
        // 详情
        this.handleView(row, 'showVersion')
      } else if ('copy' === command) {
        // 复制
        const res = await api.copyApi({ apiId: row.apiId })
        if (res.code === '200') {
          this.$message.success('复制成功！')
          this.handleQuery()
        }
      }
    },
    // 测试按钮
    // submitForm: debounceWrapper(function () {
    //   const promise = api.testApi(this.editForm.data);
    //   promise.then((response) => {
    //     if (response.code === 200) {
    //       this.msgSuccess("测试成功");
    //       this.operationResults = response.data;
    //     } else {
    //       this.operationResults = response.data;
    //     }
    //   });
    // }),
    async checkJson() {
      const res = await api.testApi({
        apiId: this.editForm.data.apiId,
        apiVersion: this.editForm.data.apiVersion,
        reqBodyBase64: Base64.encode(this.editorValue)
      })
      if (res.code === '200') {
        this.msgSuccess('测试成功')
        this.operationResults = res.data
      }
    },
    handleDialogClose() {
      this.$emit('update:modelValue', false)
    },
    handleApiSelect(list, item) {
      this.selection = list
    },
    submit() {
      if (!this.selection.length) {
        ElMessage.error('请选择一个api接口!')
        return
      }
      this.$emit('submit', this.selection[0])
      this.handleDialogClose()
    }
  }
}
</script>

<style lang="scss" scoped>
$border: 1px solid rgba(220, 223, 230, 1);

.app-dialog {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: space-between;

  .conn-api-left {
    width: 20%;
    height: 100%;
    margin-right: 10px;

    nav {
      width: 100%;
      height: 60px;
      background-color: rgb(235, 237, 240);
      line-height: 60px;
      color: #000;
      font-size: 18px;
      padding-left: 10px;
    }

    .content {
      width: 100%;
      height: 100%;
      border: $border;
      padding: 10px;

      .conetnt-box {
        width: 100%;
        height: 95%;
        margin-top: 10px;
        overflow: hidden;
        overflow-y: auto;
      }

      .conetnt-btn {
        width: 100%;
        height: 50px;
        border: none;
        text-align: left;
        margin-left: 0;
        color: #000;
      }

      .conetnt-btn:hover {
        background-color: rgb(242, 242, 242) !important;
      }

      .a {
        color: #000;
        background-color: rgb(242, 242, 242);
      }
    }
  }

  .conn-api-right {
    width: calc(80% - 10px);
    height: 100%;
    border: $border;
    padding: 10px;

    .mb8 {
      margin-left: 0 !important;
      margin-right: 0 !important;
    }
  }
}

.open-nav {
  height: 30px;
  line-height: 30px;
  display: flex;
  font-size: 16px;
  color: #000;
  margin: 0 0 10px;

  .blue-box {
    background-color: #3ca1ff;
    width: 4px;
    height: 30px;
    margin-right: 6px;
  }
}
.tips {
  color: #999;
  padding: 10px 0 0 10px;
}
.qqt-title {
  display: flex;
  align-items: center;
  gap: 8px;
  .label {
    font-size: 18px;
  }
  .add {
    cursor: pointer;
    font-size: 24px;
    font-weight: 700;
  }
}
.dialog-footer {
  display: block;
  text-align: right;
  margin: 30px 0 20px;
}
</style>
<style lang="scss">
/* required class */
.my-editor {
  background: #2d2d2d;
  color: #ccc;

  font-family:
    Fira code,
    Fira Mono,
    Consolas,
    Menlo,
    Courier,
    monospace;
  font-size: 14px;
  line-height: 1.5;
  padding: 5px;
}

/* optional */
.prism-editor__textarea:focus {
  outline: none;
}

/* not required: */
.height-300 {
  height: 300px;
}
</style>
